home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / wil4c10.zip / ASYNC.C < prev    next >
C/C++ Source or Header  |  1997-07-26  |  15KB  |  475 lines

  1. /*
  2. **  ASYNC.C
  3. **
  4. **  AsyncExpectedRead    After connecting/writing to server, we expect...
  5. **  ==================   ================================================
  6. **  ASYNC_NONE == 0      No response line(s).
  7. **  ASYNC_SINGLE_LINE    Single line of text from server.
  8. **  ASYNC_MULTIPLE_LINES Multiple lines of text from server, last with '.'.
  9. **  ASYNC_SINGLE_CODED   Single line of text, preceeded with code.
  10. **  ASYNC_MULTIPLE_CODED Multiple lines of text, preceeded with code.
  11. **  ASYNC_PLUS_MINUS     Single line of text, preceeded with + or - [POP3].
  12. **
  13. **  WINSOCK.H defines:
  14. **
  15. **  FD_READ    =  1  ( 0x01 )
  16. **  FD_WRITE   =  2  ( 0x02 )
  17. **  FD_OOB     =  4  ( 0x04 )
  18. **  FD_ACCEPT  =  8  ( 0x08 )
  19. **  FD_CONNECT = 16  ( 0x10 )
  20. **  FD_CLOSE   = 32  ( 0x20 )
  21. */
  22.  
  23. #include <windows.h>
  24. #include <winsock.h>
  25.  
  26. #include "wil.h"
  27. #include "async.h"
  28. #include "paint.h"
  29. #include "str.h"
  30.  
  31. #define QUOTE   0x22
  32. #define MAX_BUF  128
  33.  
  34. #if 1
  35. /* no prefix */
  36. #define SERVER_PREFIX
  37. #define CLIENT_PREFIX
  38. #else
  39. #define SERVER_PREFIX  DisplayString("S:");
  40. #define CLIENT_PREFIX  DisplayString("C:");
  41. #endif
  42.  
  43. /* WM_USER messages are reserved for WIL async events */
  44.  
  45. static int   TheSocket = 0;          /* the socket */
  46. static int   AsyncExpectedRead = 0;  /* expected read type [defined in ASYNC.H] */
  47. static int   AsyncSuccessMsg = 0;    /* success message */
  48. static int   AsyncFailureMsg = 0;    /* failure message */
  49. static int   AsyncReadCount = 0;     /* number of lines read */
  50. static int   AsyncResponse = 0;      /* numeric response code from server */
  51. static int   AsyncCmdLength = 0;     /* length of AsyncCmdText[] */
  52. static LPSTR AsyncCmdPtr = NULL;     /* pointer to AsyncCmdText[] */
  53. static char  AsyncCmdText[MAX_BUF];  /* command text buffer */
  54. static char  InBuffer[MAX_BUF];      /* input buffer */
  55. static char  Temp[MAX_BUF+16];       /* temporary buffer */
  56. static ULONG HostAddr = 0;           /* host address */
  57. static HWND  hMainWnd = (HWND)0;     /* main window handle */
  58. static int   EchoFlag = TRUE;        /* echo flag */
  59. static int   DebugFlag = FALSE;      /* debug flag */
  60. static int   MsgEnabled = 0;         /* FD_* messages allowed */
  61.  
  62. /* display error text & post message */
  63.  
  64. void PostError(int Code, LPSTR Text, int UserMsg)
  65. {MsgEnabled = 0;
  66.  wilAwaitCancel(TheSocket, hMainWnd);
  67.  wsprintf((LPSTR)Temp,"Async Error %d: ",Code);
  68.  DisplayString((LPSTR)Temp);
  69.  if(Text) DisplayString((LPSTR)Text);
  70.  if(Code<0)
  71.    {wilErrorText(Code,(LPSTR)Temp,MAX_BUF);
  72.     DisplayLine((LPSTR)Temp);
  73.    }
  74.  if(UserMsg) POST_MSG(UserMsg);
  75. }
  76.  
  77. /* attempt connection to server */
  78.  
  79. SOCKET AsyncConnect(HWND hWnd,  /* window to post messages */
  80.              LPSTR ServerType,  /* server type (eg: mail.iquest.com) */
  81.              LPSTR ServerName,  /* server name (eg: POP3) */
  82.                      int Port,  /* sever port */
  83.                int SuccessMsg,  /* wParam for WM_MSG if successful */
  84.                int FailureMsg,  /* wParam for WM_MSG if failure */
  85.                int ExpectRead)  /* expected response type after connecting */
  86. {int Code;
  87.  /* save parms */
  88.  hMainWnd = hWnd;
  89.  AsyncSuccessMsg = SuccessMsg;
  90.  AsyncFailureMsg = FailureMsg;
  91.  AsyncExpectedRead = ExpectRead;
  92.  AsyncResponse = 0;
  93.  wsprintf((LPSTR)Temp,"Looking for %s server %c%s%c",
  94.          (LPSTR)ServerType,QUOTE,(LPSTR)ServerName,QUOTE);
  95.  DisplayLine((LPSTR)Temp);
  96.  /* get server IP addresss */
  97.  Code = wilAskHostByName((LPSTR)ServerName);
  98.  if(Code<0)
  99.    {PostError(Code,"No such server: ",0);
  100.     return (SOCKET)0;
  101.    }
  102.  /* get host address */
  103.  HostAddr = wilGetHostAddr(0);
  104.  if(HostAddr==0)
  105.    {PostError(0, "Cannot get IP addess", 0);
  106.     return (SOCKET)0;
  107.    }
  108.  /* display server address */
  109.  wsprintf((LPSTR)Temp,"Address of server is %s\n", wilGetHostDotted(0) );
  110.  DisplayLine((LPSTR)Temp);
  111.  /* create TCP socket */
  112.  TheSocket = wilTcpSocket();
  113.  if((int)TheSocket<0)
  114.    {PostError((int)TheSocket,"Socket error: ",0);
  115.     return (SOCKET)0;
  116.    }
  117.  /* WM_USER message will be sent when connect is completed */
  118.  MsgEnabled = FD_CONNECT;
  119.  wilAwaitConnect(TheSocket,hMainWnd);
  120.  /* initiate connection to remote host */
  121.  DisplayString("Connecting to server ... ");
  122.  Code = wilConnect(TheSocket,HostAddr,Port);
  123.  if(Code<0)
  124.    {PostError(Code,"Connect: ",0);
  125.     return (SOCKET)0;
  126.    }
  127.  /* waiting for connection */
  128.  return TheSocket;
  129. }
  130.  
  131. /* await server text */
  132.  
  133. int AsyncRead(int SuccessMsg,  /* wParam for WM_MSG if successful */
  134.               int FailureMsg,  /* wParam for WM_MSG if failure */
  135.               int ReadType)    /* async read type */
  136. {
  137.  if(DebugFlag)
  138.    {wsprintf((LPSTR)Temp,"AsyncRead(%d,%d)", SuccessMsg, FailureMsg);
  139.     DisplayLine((LPSTR)Temp);
  140.    }
  141.  AsyncSuccessMsg = SuccessMsg;
  142.  AsyncFailureMsg = FailureMsg;
  143.  AsyncExpectedRead = ReadType;
  144.  AsyncReadCount = 0;
  145.  AsyncResponse = 0;
  146.  MsgEnabled = FD_READ;
  147.  wilAwaitRead(TheSocket,hMainWnd);
  148.  return TRUE;
  149. }
  150.  
  151. /* send text to server */
  152.  
  153. int AsyncWrite(LPSTR Command,  /* command to send to server */
  154.               int SuccessMsg,  /* wParam for WM_MSG if successful */
  155.               int FailureMsg)  /* wParam for WM_MSG if failure */
  156. {
  157.  if(Command==NULL) return FALSE;
  158.  if(DebugFlag)
  159.    {wsprintf((LPSTR)Temp,"AsyncWrite(%c%s%c,%d,%d)",
  160.                  QUOTE, Command, QUOTE,
  161.                  SuccessMsg, FailureMsg);
  162.     DisplayLine((LPSTR)Temp);
  163.    }
  164.  AsyncSuccessMsg = SuccessMsg;
  165.  AsyncFailureMsg = FailureMsg;
  166.  AsyncExpectedRead = ASYNC_NONE;
  167.  StringCopy((LPSTR)AsyncCmdText, (LPSTR)Command, MAX_BUF);
  168.  AsyncCmdLength = lstrlen((LPSTR)AsyncCmdText);
  169.  AsyncCmdPtr = (LPSTR) &AsyncCmdText[0];
  170.  MsgEnabled = FD_WRITE;
  171.  wilAwaitWrite(TheSocket,hMainWnd);
  172.  return TRUE;
  173. }
  174.  
  175. /* send text to server, then await response */
  176.  
  177. int AsyncCommand(LPSTR Command, /* command to send to server       */
  178.               int SuccessMsg,   /* wParam for WM_MSG if successful */
  179.               int FailureMsg,   /* wParam for WM_MSG if failure    */
  180.               int ExpectRead)   /* expected response type (if any) */
  181. {
  182.  if(Command==NULL) return FALSE;
  183.  if(DebugFlag)
  184.    {wsprintf((LPSTR)Temp,"AsyncCommand(%c%s%c,%d,%d,%d)",
  185.                  QUOTE, Command, QUOTE,
  186.                  SuccessMsg, FailureMsg, ExpectRead);
  187.     DisplayLine((LPSTR)Temp);
  188.    }
  189.  AsyncSuccessMsg = SuccessMsg;
  190.  AsyncFailureMsg = FailureMsg;
  191.  AsyncExpectedRead = ExpectRead;
  192.  AsyncCmdPtr = (LPSTR) &AsyncCmdText[0];
  193.  StringCopy(AsyncCmdPtr, Command, MAX_BUF);
  194.  AsyncCmdLength = lstrlen((LPSTR)AsyncCmdText);
  195.  MsgEnabled = FD_WRITE;
  196.  wilAwaitWrite(TheSocket,hMainWnd);
  197.  return TRUE;
  198. }
  199.  
  200. /*
  201. ** AsyncProcessMsg should be called from the WM_USER case
  202. ** event loop of the main program.
  203. **
  204. ** It returns TRUE if the message was recognized.
  205. */
  206.  
  207. int AsyncProcessMsg(LONG lParam)
  208. {int Code;
  209.  /* process WM_USER message */
  210.  switch( LOWORD(lParam) )
  211.    {
  212.     case FD_CONNECT:
  213.       /* connection to server is completed */
  214.       if(MsgEnabled!=FD_CONNECT) return TRUE;
  215.       DisplayLine("Connection complete.");
  216.       /* do we expect a response from the server ? */
  217.       if(AsyncExpectedRead)
  218.         {/* expect a response from server */
  219.          MsgEnabled = FD_READ;
  220.          wilAwaitRead(TheSocket, hMainWnd);
  221.         }
  222.       else
  223.         {/* post the success message */
  224.          MsgEnabled = 0;
  225.          wilAwaitCancel(TheSocket, hMainWnd);
  226.          POST_MSG(AsyncSuccessMsg);
  227.         }
  228.       return TRUE;
  229.  
  230.     case FD_WRITE:
  231.       /* socket is ready for writing */
  232.       if(MsgEnabled!=FD_WRITE) return TRUE;
  233.       /* ready to write */
  234.       if(EchoFlag)
  235.         {SERVER_PREFIX
  236.          DisplayLine(AsyncCmdPtr);
  237.         }
  238.       /* transmit command */
  239.       Code = wilWriteLine(TheSocket,AsyncCmdPtr);
  240.       if(Code<0)
  241.         {PostError(Code,"Write: ",AsyncFailureMsg);
  242.          return TRUE;
  243.         }
  244.       /* more to write ? */
  245.       if(Code<AsyncCmdLength)
  246.         {/* got more to send */
  247.          AsyncCmdPtr += (Code);
  248.          AsyncCmdLength -= (Code);
  249.          return TRUE;
  250.         }
  251.       /* write is completed */
  252.       if(AsyncExpectedRead)
  253.         {/* expect a response from server */
  254.          AsyncReadCount = 0;
  255.          MsgEnabled = FD_READ;
  256.          wilAwaitRead(TheSocket, hMainWnd);
  257.         }
  258.       else
  259.         {/* no response expected form server */
  260.          MsgEnabled = 0;
  261.          wilAwaitCancel(TheSocket, hMainWnd);
  262.          /* post the success message */
  263.          POST_MSG(AsyncSuccessMsg);
  264.         }
  265.       return TRUE;
  266.  
  267.     case FD_READ:
  268.       /* socket has data */
  269.       if(MsgEnabled!=FD_READ) return TRUE;
  270.       /* incoming data ready to read */
  271.       switch(AsyncExpectedRead)
  272.         {
  273.          case ASYNC_MULTIPLE_LINES:
  274.            Code = wilReadLine(TheSocket,(LPSTR)InBuffer,MAX_BUF);
  275.            /* end of input ? */
  276.            if(Code==WIL_EOF)
  277.              {wilAwaitCancel(TheSocket, hMainWnd);
  278.               MsgEnabled = 0;
  279.               POST_MSG(AsyncSuccessMsg);
  280.               return TRUE;
  281.              }
  282.            /* error ? */
  283.            if(Code<0)
  284.              {PostError(Code,"Read1: ",AsyncFailureMsg);
  285.               return TRUE;
  286.              }
  287.            /* anything there ? */
  288.            if(Code>0)
  289.              {/* display buffer */
  290.               AsyncReadCount++;
  291.               if(EchoFlag)
  292.                 {SERVER_PREFIX
  293.                  DisplayString((LPSTR)InBuffer);
  294.                 }
  295.               /* did we just get a '.' ? on a line by itself */
  296.               if(  (*InBuffer=='.')
  297.                  &&(*(InBuffer+1)=='\r')
  298.                  &&(*(InBuffer+2)=='\n')
  299.                  &&(Code==3) )
  300.                 {wilAwaitCancel(TheSocket, hMainWnd);
  301.                  MsgEnabled = 0;
  302.                  POST_MSG(AsyncSuccessMsg);
  303.                 }
  304.               return TRUE;
  305.              }
  306.            /* Code == 0 */
  307.            return TRUE;
  308.  
  309.          case ASYNC_SINGLE_LINE:
  310.            /* expect single line from server */
  311.            AsyncReadCount++;
  312.            Code = wilReadLine(TheSocket,(LPSTR)InBuffer,MAX_BUF);
  313.            /* end of input ? */
  314.            if(Code==WIL_EOF)
  315.              {wilAwaitCancel(TheSocket, hMainWnd);
  316.               MsgEnabled = 0;
  317.               POST_MSG(AsyncSuccessMsg);
  318.               return TRUE;
  319.              }
  320.            /* error ? */
  321.            if(Code<0)
  322.              {PostError(Code,"Read2: ",AsyncFailureMsg);
  323.               return TRUE;
  324.              }
  325.            /* anything there ? */
  326.            if(Code>0)
  327.              {/* display buffer */
  328.               if(EchoFlag)
  329.                 {SERVER_PREFIX
  330.                  DisplayString((LPSTR)InBuffer);
  331.                 }
  332.              }
  333.            /* Code >= 0 */
  334.            MsgEnabled = 0;
  335.            wilAwaitCancel(TheSocket, hMainWnd);
  336.            POST_MSG(AsyncSuccessMsg);
  337.            return TRUE;
  338.  
  339.          case ASYNC_SINGLE_CODED:
  340.            AsyncReadCount++;
  341.            Code = wilWaitLine(TheSocket,(LPSTR)InBuffer,MAX_BUF, 0, 500);
  342.            /* end of input ? */
  343.            if(Code==WIL_EOF)
  344.              {wilAwaitCancel(TheSocket, hMainWnd);
  345.               MsgEnabled = 0;
  346.               POST_PARM(AsyncSuccessMsg,(long)-1);
  347.               return TRUE;
  348.              }
  349.            /* error ? */
  350.            if(Code<0)
  351.              {PostError(Code,"Read5: ",AsyncFailureMsg);
  352.               return TRUE;
  353.              }
  354.            /* anything there ? */
  355.            if(Code>0)
  356.              {/* display buffer */
  357.               if(EchoFlag)
  358.                 {SERVER_PREFIX
  359.                  DisplayString((LPSTR)InBuffer);
  360.                 }
  361.               /* fetch response code */
  362.               AsyncResponse = (int) wilParseDecimal((LPSTR)InBuffer);
  363.               /* post response code */
  364.               wilAwaitCancel(TheSocket, hMainWnd);
  365.               MsgEnabled = 0;
  366.               POST_PARM(AsyncSuccessMsg,(long)AsyncResponse);
  367.               return TRUE;
  368.              }
  369.            /* Code == 0 */
  370.            return TRUE;
  371.  
  372.          case ASYNC_MULTIPLE_CODED:
  373.            AsyncReadCount++;
  374.            Code = wilWaitLine(TheSocket,(LPSTR)InBuffer,MAX_BUF, 0, 500);
  375.            /* end of input ? */
  376.            if(Code==WIL_EOF)
  377.              {wilAwaitCancel(TheSocket, hMainWnd);
  378.               MsgEnabled = 0;
  379.               POST_PARM(AsyncSuccessMsg,(long)-1);
  380.               return TRUE;
  381.              }
  382.            /* error ? */
  383.            if(Code<0)
  384.              {PostError(Code,"Read3: ",AsyncFailureMsg);
  385.               return TRUE;
  386.              }
  387.            /* anything there ? */
  388.            if(Code>0)
  389.              {/* display buffer */
  390.               if(EchoFlag)
  391.                 {SERVER_PREFIX
  392.                  DisplayString((LPSTR)InBuffer);
  393.                 }
  394.               /* fetch response code */
  395.               Code = (int) wilParseDecimal((LPSTR)InBuffer);
  396.               if(AsyncReadCount==1) AsyncResponse = Code;
  397.               /* post response code if this is last line of coded text */
  398.               if(  (Code==AsyncResponse)
  399.                  &&( (Code == 3) || (InBuffer[3]==' ') ) )
  400.                 {wilAwaitCancel(TheSocket, hMainWnd);
  401.                  MsgEnabled = 0;
  402.                  POST_PARM(AsyncSuccessMsg,(long)AsyncResponse);
  403.                 }
  404.               return TRUE;
  405.              }
  406.            /* Code == 0 */
  407.            return TRUE;
  408.  
  409.          case ASYNC_PLUS_MINUS:
  410.            /* expect single line from server beginning with + or - */
  411.            AsyncReadCount++;
  412.            Code = wilReadLine(TheSocket,(LPSTR)InBuffer,MAX_BUF);
  413.            /* end of input ? */
  414.            if(Code==WIL_EOF)
  415.              {wilAwaitCancel(TheSocket, hMainWnd);
  416.               MsgEnabled = 0;
  417.               POST_MSG(AsyncSuccessMsg);
  418.               return TRUE;
  419.              }
  420.            /* error ? */
  421.            if(Code<0)
  422.              {PostError(Code,"Read4: ",AsyncFailureMsg);
  423.               return TRUE;
  424.              }
  425.            /* anything there ? */
  426.            if(Code>0)
  427.              {/* display buffer */
  428.               if(EchoFlag)
  429.                 {SERVER_PREFIX
  430.                  DisplayString((LPSTR)InBuffer);
  431.                 }
  432.               wilAwaitCancel(TheSocket, hMainWnd);
  433.               MsgEnabled = 0;
  434.               switch(*InBuffer)
  435.                 {case '+':
  436.                    POST_MSG(AsyncSuccessMsg);
  437.                    return TRUE;
  438.                  case '-':
  439.                    POST_MSG(AsyncFailureMsg);
  440.                    return TRUE;
  441.                  default:
  442.                    if(EchoFlag) DisplayLine("Expected +OK or -ERR");
  443.                    POST_MSG(AsyncFailureMsg);
  444.                    return TRUE;
  445.                 }
  446.              }
  447.            /* Code == 0 */
  448.            return TRUE;
  449.  
  450.          default:
  451.            MsgEnabled = 0;
  452.            return FALSE;
  453.  
  454.         } /* end-switch(AsyncExpectedRead) */
  455.     default:
  456.       return FALSE;
  457.    } /* end-switch(LOWORD(lParam)) */
  458. }
  459.  
  460. LPSTR AsyncGetBufPtr(void)
  461. {
  462.  return (LPSTR) InBuffer;
  463. }
  464.  
  465. int AsyncSetEcho(int Flag)
  466. {int Last = EchoFlag;
  467.  EchoFlag = Flag;
  468.  return Last;
  469. }
  470.  
  471. int AsyncSetDebug(int Flag)
  472. {int Last = DebugFlag;
  473.  DebugFlag = Flag;
  474.  return Last;
  475. }